package com.instagram.instadownloader.fetcher;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.os.AsyncTask;
import android.util.Log;

import com.instagram.instadownloader.utils.HttpConnection;

/**
 * The Class InstaVideoFetcher.
 * @author HuanND
 */
public class InstaVideoFetcher {

	/**
	 * Fetch.
	 *
	 * @param url the url
	 * @param listener the listener
	 */
	public void fetch(String url, OnFetcherListener listener) {
		try {
			FetchForURLVideoAT localFetchForURLVideoAT = new FetchForURLVideoAT(
					listener);
			URL[] arrayOfURL = new URL[1];
			arrayOfURL[0] = new URL(url);
			localFetchForURLVideoAT.execute(arrayOfURL);
			return;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Validate.
	 *
	 * @param paramString the param string
	 * @return the string
	 */
	public String validate(String paramString) {
		int i = 0;
		String str = paramString.trim();
		String[] arrayOfString = { "^http://www.instagram.com/p/([^/#]*)$",
				"^http://instagram.com/p/(.*)/$",
				"^http://instagram.com/p/(.*)/#$" };
		int j = arrayOfString.length;
		while (true) {
			if (i >= j)
				return "";
			if (str.matches(arrayOfString[i])) {
				Log.e("huannd", str);
				if (str.endsWith("#"))
					str = str.replace("#", "");
				if (!str.endsWith("/"))
					str = str + "/";
				while (true)
					return str.replaceAll(" ", "");
			}
			i++;
		}
	}

	/**
	 * Parses the html.
	 *
	 * @param paramInputStream the param input stream
	 * @return the list
	 */
	public List<String> parseHTML(InputStream paramInputStream) {
		ArrayList<String> localArrayList = new ArrayList<String>();
		BufferedReader localBufferedReader = new BufferedReader(
				new InputStreamReader(paramInputStream));
		while (true) {
			String str = null;
			try {
				str = localBufferedReader.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (str == null)
				return localArrayList;
			if ((!str.contains("<meta")) && (!str.contains("<title>")))
				continue;
			localArrayList.add(str);
		}

	}

	/**
	 * Parses the instagram name.
	 *
	 * @param paramString the param string
	 * @return the string
	 */
	public String parseInstagramName(String paramString) {
		if (paramString == null)
			return "";
		if ("".equals(paramString.trim()))
			return "";
		String str = paramString.trim();
		Matcher localMatcher = Pattern
				.compile("^http://instagram.com/p/(.*)/$").matcher(str);
		if (localMatcher.matches())
			return localMatcher.group(1);
		return "";
	}

	/**
	 * Search for image url.
	 *
	 * @param paramList the param list
	 * @return the string
	 */
	public String searchForImageURL(List<String> paramList) {
		Pattern localPattern = Pattern
				.compile("meta property=\"og:image\" content=\"(.*)\"");
		Iterator localIterator = paramList.iterator();
		Matcher localMatcher;
		do {
			if (!localIterator.hasNext())
				return "";
			localMatcher = localPattern.matcher((String) localIterator.next());
		} while (!localMatcher.find());
		if (localMatcher.group(1).contains("http://")
				|| localMatcher.group(1).contains("https://"))
			return localMatcher.group(1);
		return "";
	}

	/**
	 * Search for page not found instagram.
	 *
	 * @param paramList the param list
	 * @return true, if successful
	 */
	public boolean searchForPageNotFoundInstagram(List<String> paramList) {
		Pattern localPattern = Pattern.compile(".*<title>Page Not Found.*");
		Iterator localIterator = paramList.iterator();
		do
			if (!localIterator.hasNext())
				return false;
		while (!localPattern.matcher((String) localIterator.next()).find());
		return true;
	}

	/**
	 * Search for video url.
	 *
	 * @param paramList the param list
	 * @return the string
	 */
	public String searchForVideoURL(List<String> paramList) {
		Pattern localPattern = Pattern
				.compile("meta property=\"og:video\" content=\"(.*)\"");
		Iterator localIterator = paramList.iterator();
		Matcher localMatcher;
		do {
			if (!localIterator.hasNext())
				return "";
			localMatcher = localPattern.matcher((String) localIterator.next());
		} while (!localMatcher.find());
		if (localMatcher.group(1).matches("^http://(.*).mp4$"))
			return localMatcher.group(1);
		return "";
	}

	/**
	 * The Class HTMLParsingException.
	 */
	public class HTMLParsingException extends Exception {
		
		/**
		 * Instantiates a new HTML parsing exception.
		 *
		 * @param arg2 the arg2
		 */
		public HTMLParsingException(String arg2) {
			super();
		}
	}

	/**
	 * The Class FetchForURLVideoAT.
	 */
	public class FetchForURLVideoAT extends AsyncTask<URL, Void, Void> {
		
		/** The video url. */
		private String videoUrl;
		
		/** The image url. */
		private String imageUrl;
		
		/** The m fetcher listener. */
		private OnFetcherListener mFetcherListener;

		/**
		 * Instantiates a new fetch for url video at.
		 *
		 * @param listener the listener
		 */
		public FetchForURLVideoAT(OnFetcherListener listener) {
			mFetcherListener = listener;
		}

		/* (non-Javadoc)
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		@Override
		protected Void doInBackground(URL[] paramArrayOfURL) {
			try {
				InputStream localInputStream = HttpConnection.connectGetMethod(
						paramArrayOfURL[0].toString(), null);
				List localList = InstaVideoFetcher.this
						.parseHTML(localInputStream);
				if (InstaVideoFetcher.this
						.searchForPageNotFoundInstagram(localList)) {
					return null;
				}
				videoUrl = InstaVideoFetcher.this.searchForVideoURL(localList);
				imageUrl = InstaVideoFetcher.this.searchForImageURL(localList);
			} catch (Exception e) {

			}
			return null;
		}

		/* (non-Javadoc)
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			if (mFetcherListener != null) {
				FetcherData data = new FetcherData();
				data.setImageUrl(imageUrl);
				data.setVideoUrl(videoUrl);
				mFetcherListener.onFetcherComplete(data);
			}
		}
	}

	/**
	 * The listener interface for receiving onFetcher events.
	 * The class that is interested in processing a onFetcher
	 * event implements this interface, and the object created
	 * with that class is registered with a component using the
	 * component's <code>addOnFetcherListener<code> method. When
	 * the onFetcher event occurs, that object's appropriate
	 * method is invoked.
	 *
	 * @see OnFetcherEvent
	 */
	public interface OnFetcherListener {
		
		/**
		 * On fetcher fail.
		 *
		 * @param message the message
		 */
		public void onFetcherFail(String message);

		/**
		 * On fetcher complete.
		 *
		 * @param data the data
		 */
		public void onFetcherComplete(FetcherData data);
	}

}
